home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / sys / m68k / 227 / uart.uc
Encoding:
Text File  |  1996-08-05  |  22.1 KB  |  458 lines

  1. (**********************************************************************)
  2. (*                                                                    *)
  3. (* Function:    UART    Universal Asynchronous Receiver / Transmitter *)
  4. (*                                                                    *)
  5. (* Creation Date: 27/Jul/92                  From: NEW                *)
  6. (*                                                                    *)
  7. (* Author:  Josef Fuchs / Ewald Liess                                 *)
  8. (*                                                                    *)
  9. (* Description:                                                       *)
  10. (* ------------                                                       *)
  11. (* This function uses 1 or 2 TPU channels to form a uni or bidirection*)
  12. (* UART. Baud rate is freely programmable by the user. The data word  *)
  13. (* length can be between 1 and 14 bits and no/odd/even parity is      *)
  14. (* supported. The function has been designed to operate in a similar  *)
  15. (* manner to the SCI port found on many Motorola MCUs. The function is*)
  16. (* double buffered i.e there is a shift reg. and data reg.            *)
  17. (* All 16 TPU channels could be used for UART, each operating at more *)
  18. (* than 9600 baud.                                                    *)
  19. (*                                                                    *)
  20. (* Updates:   By:   Modification:                                     *)
  21. (* --------   ---   -------------                                     *)
  22. (*  RevB      JW    Added interrupt generation to transmitter init    *)
  23. (*                  - state2                                          *)
  24. (* 16/Jun/93  JW    Moved receiver interrupt generation to be after   *)
  25. (*                  data write for correct polled operation.          *)
  26. (*                  Designated as rev 1.0 for mask release.           *)
  27. (* 12/Aug/93  JL    Converted to new TPUMASM syntax                   *)
  28. (*                                                                    *)
  29. (*--------------------------------------------------------------------*)
  30. (* Standard Exits Used:-   End_Of_Phase: N         End_Of_Link: Y     *)
  31. (*                                                                    *)
  32. (* External Files included: NONE                                      *)
  33. (*                                                                    *)
  34. (* CODE SIZE excluding standard exits = 67 LONG WORDS                 *)
  35. (*--------------------------------------------------------------------*)
  36. (*                                                                    *)
  37. (*                                                                    *)
  38. (**********              This Revision:  1.1                  *********)
  39. (*                                                                    *)
  40. (**********   LAST MODIFIED: 12/Aug/93       BY: Jeff Loeliger ********)
  41. (*                                                                    *)
  42. (**********************************************************************)
  43. (***************************************************************************)
  44. (*Motorola reserves the right to make changes without further notice to any*)
  45. (*product herein. Motorola makes no warranty, representation or guarantee  *)
  46. (*regarding the suitability of its products for any particular purpose, nor*)
  47. (*does Motorola assume any liability arising out of the application or use *)
  48. (*of any product or circuit, and specifically disclaims any and all        *)
  49. (*liability, including without limitation consequential or incidental      *)
  50. (*damages. "Typical" parameters can and do vary in different applications. *)
  51. (*All operating parameters, including "Typical",must be validated for each *)
  52. (*customer application by customer's technical experts. Motorola does not  *)
  53. (*convey any license under its patent rights nor the rights of others.     *)
  54. (*Motorola products are not designed, intended, or authorized for use as   *)
  55. (*components in systems intended for surgical implant into the body, or    *)
  56. (*other applications intended to support or sustain life, or for any other *)
  57. (*application in which the failure of the Motorola product could create a  *)
  58. (*situation where injury or death may occur. Should Buyer purchase or use  *)
  59. (*Motorola products for any such unintended or unauthorized application,   *)
  60. (*Buyer, shall indemnify and hold Motorola and its officers, employees,    *)
  61. (*subsidiaries, affiliates, and distributors harmless against all claims,  *)
  62. (*costs, damages, and expenses, and reasonable attorney fees arising out   *)
  63. (*of, directly or indirectly, any claim of personal injury or death        *)
  64. (*associated with such unintended or unauthorized use, even if such claim  *)
  65. (*alleges that Motorola was negligent regarding the design or manufacture  *)
  66. (*of the part.                                                             *)
  67. (*Motorola and the Motorola logo are registered trademarks of Motorola Inc.*) 
  68. (*Motorola is an Equal Opportunity/Affirmative Action Employer.            *)
  69. (*Copyright Motorola Inc. 1993                                             *)
  70. (***************************************************************************)
  71.  
  72.  
  73. (*()()()()()()()()()()() DATA STRUCTURE ()()()()()()()()()()()()()()()*)
  74. (*                                                                    *)
  75. (* name:               Written By:            Location  Bits:         *)
  76. (* -----               -----------            ---------------         *)
  77. (* PARITY_TEMP            TPU                 Parameter0  0..15       *)
  78. (*                     Used by TPU to calculate parity - CPU must not *)
  79. (*                     write.                                         *)
  80. (*                                                                    *)
  81. (* MATCH_RATE             CPU                 Parameter1  0..15       *)
  82. (*                     Baud period in TCR1 clocks.                    *)
  83. (*                                                                    *)
  84. (* DATA                   BOTH                Parameter2  0..15       *)
  85. (*                     Transmit or Receive data register. For transmit*)
  86. (*                     ,bit 15 must be 0.                             *)
  87. (*                                                                    *)
  88. (* DATA_SIZE              CPU                 Parameter3  0..15       *)
  89. (*                     Holds the number of bits in a data word -      *)
  90. (*                     INCLUDING parity.                              *)
  91. (*                                                                    *)
  92. (* ACTUAL_BIT_COUNT       TPU                 Parameter4  0..15       *)
  93. (*                     Used by the TPU to count the number of bits.   *)
  94. (*                     CPU must not write.                            *)
  95. (*                                                                    *)
  96. (* SHIFT_REG              TPU                 Parameter5  0..15       *)
  97. (*                     Used by the TPU for shifting in/out data.      *)
  98. (*                     CPU must not write.                            *)
  99. (*                                                                    *)
  100. (*                                                                    *)
  101. (* HSQ1   HSQ0         Action                                         *)
  102. (* ----   ----         ------                                         *)
  103. (*  0       0          No Parity.                                     *)
  104. (*  0       1          No Parity.                                     *)
  105. (*  1       0          Even Parity.                                   *)
  106. (*  1       1          Odd Parity.                                    *)
  107. (*                                                                    *)
  108. (* hsr1   hsr0         Action                                         *)
  109. (* ----   ----         ------                                         *)
  110. (*  0       x          No action                                      *)
  111. (*  1       0          Initialise channel as receiver. [clfg1 cleared]*)
  112. (*  1       1          Initialise chan as transmitter. [cflg1 set]    *)
  113. (*                                                                    *)
  114. (* Links Accepted: NO              Links Generated: NO                *)
  115. (*                                                                    *)
  116. (* Interrupts Generated After:   Transmit data empty/receive data full*)
  117. (*                                                                    *)
  118. (*()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()*)
  119.  
  120. (*+++++++++++++++++++++  PARAMETER MACROS  +++++++++++++++++++++++++++*)
  121.  
  122. %macro PARITY_TEMP_UART      'prm0'.
  123. %macro MATCH_RATE_UART       'prm1'.
  124. %macro DATA_UART             'prm2'.
  125. %macro DATA_SIZE_UART        'prm3'.
  126. %macro ACTUAL_BIT_COUNT_UART 'prm4'.
  127. %macro SHFT_REG_UART         'prm5'.
  128.  
  129. (* conditions *)
  130. %macro RECEIVER_UART      'flag1 = 0'.  (* Receiver is selected by cflag1=0 *)
  131. %macro PARITY_OFF_UART    'hsq1 = 0'.   (* no Parity *)
  132. %macro PARITY_EVEN_UART   'hsq0 = 0'.   (* use even Parity *)
  133.  
  134.  
  135. (*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  136.  
  137.  
  138. (*====================================================================*)
  139. (*|||||||||||||||||||||  MICROCODE STARTS BELOW  |||||||||||||||||||||*)
  140. (*VVVVVVVVVVVVVVVVVVVVV--------------------------VVVVVVVVVVVVVVVVVVVVV*)
  141.  
  142.  
  143.  
  144. (**********************************************************************)
  145. (*                                                                    *)
  146. (* State 1: Initialisation for RECEIVER                               *)
  147. (*                                                                    *)
  148. (* entered by HSR 2                                                   *)
  149. (**********************************************************************)
  150.  
  151. %entry  start_address *;disable_match;
  152. name = INIT_RECEIVER_UART;
  153. cond hsr1 = 1, hsr0 = 0.
  154.  
  155. INIT_RECEIVER_UART:   chan tbs := in_m1_c1,
  156.                       pac := high_low;
  157.                       chan clear flag0; (*wait for start-bit = falling edge *)
  158.                       enable_mtsr.
  159.  
  160.                       chan neg_tdl, neg_mrl, neg_lsl;
  161.                       chan clear flag1;                  (* select RECEIVER *)
  162.                       end.
  163.  
  164.  
  165.  
  166. (**********************************************************************)
  167. (*                                                                    *)
  168. (* State 2: Initialisation for TRANSMITTER                            *)
  169. (*                                                                    *)
  170. (* entered by HSR 3                                                   *)
  171. (**********************************************************************)
  172.  
  173. %entry  ram p <- @MATCH_RATE_UART; start_address *;disable_match;
  174. name = INIT_TRANSMIT_UART;
  175. cond hsr1 = 1, hsr0 = 1.
  176.  
  177. INIT_TRANSMIT_UART:   chan tbs := out_m1_c1,
  178.                       pac := no_change,
  179.                       pin := high;
  180.                       chan clear flag0;           (* poll the TDRE-bit *)
  181.                       enable_mtsr.
  182.  
  183.                       au   ert := tcr1 + p;
  184.                       chan neg_tdl, neg_mrl, neg_lsl;
  185.                       write_mer;
  186.                       chan set flag1;           (* select TRANSMITTER *)
  187.                       chan cir;        (* revB - for IRQ driven transmitter *)
  188.                       end.
  189.  
  190.  
  191.  
  192. (**********************************************************************)
  193. (*                                                                    *)
  194. (* if TRANSMITTER then     State 3: POLLING TDRE                      *)
  195. (* else RECEIVER then goto STATE 5: FALLING EDGE DETECTED             *)
  196. (*                                                                    *)
  197. (* For Transmitter:                                                   *)
  198. (* entered after a match if no data is sent out, then:                *)
  199. (* if TDRE is set: set up next match to test TDRE again               *)
  200. (*     else set cflag0 to indicate transmittion and send startbit     *)
  201. (*                                                                    *)
  202. (* For Receiver:                                                      *)
  203. (* entered after a falling edge (of startbit) is detected,            *)
  204. (* then goto State 5 (receive startbit)                               *)
  205. (**********************************************************************)
  206.  
  207. %entry ram diob <- @MATCH_RATE_UART; start_address *; disable_match;
  208. name = SERV_START_BIT_UART;
  209. cond hsr1 = 0, hsr0 = 0, m/tsr = 1,lsr = 0, pin = x,flag0 = 0.
  210.  
  211. SERV_START_BIT_UART:
  212.                  if   @RECEIVER_UART then goto RXD_START_BIT_UART.
  213.                                                           (* Goto Receiver *)
  214.  
  215.                  au   p := 0;
  216.                  ram  p -> @PARITY_TEMP_UART.    (* reset high-bit counter *)
  217.  
  218. (* following statements are for transmitter only *)
  219.  
  220.                  au   ert := ert + diob;          (* define first match *)
  221.                  chan neg_mrl, neg_lsl, neg_tdl;
  222.                       write_mer.
  223.  
  224.                  ram  p <- @DATA_UART.
  225.  
  226.                  au   nil := p, ccl;               (* test TDRE *)
  227.                  ram  diob <- @DATA_SIZE_UART.
  228.  
  229.                  if   N = 1 then goto END_OF_LINK,flush.
  230.  
  231. (* valid data found, send it *)
  232.  
  233. SEND_START_BIT_UART:
  234.                  chan pac := low;                 (* start bit *)
  235.                  chan set flag0;                  (* now send data *)
  236.                  chan cir.
  237.  
  238.                  au   diob := diob+1;             (* count also startbit *)
  239.                  ram  diob -> @ACTUAL_BIT_COUNT_UART.
  240.  
  241.                  au   p := p + max;              (* chan set TDRE-Bit = MSB *)
  242.                  ram  p -> @SHFT_REG_UART.   (* copy data to shift register *)
  243.  
  244.                  ram  p -> @DATA_UART;         (* chan set TDRE in Dataword *)
  245.                  end.
  246.  
  247.  
  248.  
  249. (**********************************************************************)
  250. (*                                                                    *)
  251. (* if TRANSMITTER then     State 4: send data bits                    *)
  252. (* else if RECEIVER then goto STATE 6: receive data bits              *)
  253. (*                                                                    *)
  254. (* Read the Data and shift the LSB-Bit out, then write the shifted    *)
  255. (* value into the SHFT_REG and decrement ACTUAL_BIT_COUNT.            *)
  256. (**********************************************************************)
  257.  
  258. %entry  ram diob <- @MATCH_RATE_UART; start_address *; disable_match;
  259. name = SERV_DATA_BITS_UART;
  260. cond hsr1 = 0, hsr0 = 0, m/tsr = 1, lsr = 0, pin = x, flag0 = 1.
  261.  
  262. SERV_DATA_BITS_UART:
  263.                  au   ert := ert + diob;
  264.                  ram  p <- @ACTUAL_BIT_COUNT_UART.
  265.  
  266.                  if   @RECEIVER_UART then goto RXD_DATA_BIT_UART.
  267.                                                           (* Goto Receiver *)
  268.  
  269.                  au   p := p - 1, ccl;        (* decrement number of bits *)
  270.                  ram  p -> @ACTUAL_BIT_COUNT_UART.
  271.  
  272. (* following statements are for transmitter only *)
  273.  
  274.                  if   N = 1 then goto SEND_STOP_BIT_UART,flush.
  275.  
  276.                  if   Z = 1 then goto SEND_PARITY_UART,flush.
  277.  
  278.                  ram  p <- @SHFT_REG_UART.
  279.  
  280.                  ram  diob <- @PARITY_TEMP_UART.
  281.  
  282. SEND_BIT_UART:   au   p :=>> p, ccl;              (* shift out data bit *)
  283.                  ram  p -> @SHFT_REG_UART.
  284.  
  285.                  if   C = 1 then goto SEND_HIGH_BIT_UART,flush.
  286.  
  287. SEND_LOW_BIT_UART:
  288.                  chan pac := low;
  289.                  neg_tdl, neg_lsl, neg_mrl;
  290.                  write_mer;
  291.                  end.
  292.  
  293. SEND_HIGH_BIT_UART:
  294.                  au   diob:= diob+1;          (* update parity *)
  295.                  ram  diob -> @PARITY_TEMP_UART.
  296.  
  297.                  chan pac := high;
  298.                       neg_tdl, neg_lsl, neg_mrl;
  299.                       write_mer;
  300.                  end.
  301.  
  302. SEND_PARITY_UART:
  303.                  if   @PARITY_OFF_UART then goto SEND_STOP_BIT_UART,flush.
  304.  
  305.                  if   @PARITY_EVEN_UART then goto SEND_BIT_UART.
  306.  
  307.                  ram  p <- @PARITY_TEMP_UART.
  308.  
  309.                  goto SEND_BIT_UART.
  310.  
  311.                  au   p := p + 1.  (* generate odd parity = do a complement *)
  312.  
  313. SEND_STOP_BIT_UART:
  314.                  chan pac := high;
  315.                       neg_tdl, neg_lsl, neg_mrl;
  316.                       write_mer;
  317.                  chan clear flag0;
  318.                  end.
  319.  
  320.  
  321. (**********************************************************************)
  322. (*                                                                    *)
  323. (* STATE 5: FALLING EDGE DETECTED                                     *)
  324. (*                                                                    *)
  325. (* START-Bit and start sampling in the middle of a BIT                *)
  326. (* = set up a match after 1.5 bittimes                                *)
  327. (*                                                                    *)
  328. (* Parity Temp already cleared, diob contains Matchrate               *)
  329. (*                                                                    *)
  330. (**********************************************************************)
  331.  
  332. RXD_START_BIT_UART:
  333.                  au   ert:=ert+diob;
  334.                  ram  p <- @DATA_SIZE_UART.
  335.  
  336.                  if   @PARITY_OFF_UART then goto RXD_NO_PARITY_UART,flush.
  337.  
  338.                  au   p := p + 1.       (* count also parity bit if enabled *)
  339.  
  340. RXD_NO_PARITY_UART:
  341.                  ram  p -> @ACTUAL_BIT_COUNT_UART;
  342.                  au   diob :=>> diob.            (* MATCHRATE/2 *)
  343.  
  344.                  au   ert := ert + diob;       (* ert := ert +1.5*Matchrate *)
  345.                  chan pac := no_detect; chan set flag0;
  346.                       neg_mrl, neg_lsl, neg_tdl;
  347.                       write_mer;
  348.                  end.
  349.  
  350.  
  351.  
  352. (**********************************************************************)
  353. (*                                                                    *)
  354. (* STATE 6: RECEIVE BITS                                              *)
  355. (*                                                                    *)
  356. (* Read the value at the pin and shift this value in the SHFT_REG.    *)
  357. (* Also decrement ACTUAL_BIT_CNT (the number of received bits).       *)
  358. (*                                                                    *)
  359. (* diob contains Matchrate, ert already set up with ert+diob          *)
  360. (* no write_mer issued !!                                             *)
  361. (* Actual_Bit_Count is already decremented ccl set by decrement       *)
  362. (**********************************************************************)
  363.  
  364. RXD_DATA_BIT_UART:
  365.                 if   N = 1 then goto RECEIVE_STOP_UART.
  366.  
  367.                 au   a := 0;                    (* clear FLAG-BITS *)
  368.                 ram  diob <- @SHFT_REG_UART.      (* read shiftregister *)
  369.  
  370. (* there is a data bit to receive *)
  371.  
  372.                 if   psl = 1 then goto RECEIVE_HIGH_UART.
  373.                                              (* high bit has to be received *)
  374.                 au   diob :=>> diob;               (* shift zero into BIT15 *)
  375.                 chan neg_tdl, neg_lsl, neg_mrl;
  376.                      write_mer.
  377.  
  378. RECEIVE_LOW_UART:
  379.                 ram  diob -> @SHFT_REG_UART;            (* get the low bit *)
  380.                end.
  381.  
  382. RECEIVE_HIGH_UART:
  383.                au   diob := diob + max; (* chan set received bit, shifted before *)
  384.                ram  diob -> @SHFT_REG_UART.
  385.  
  386.                ram  diob <- @PARITY_TEMP_UART.         (* add parity *)
  387.  
  388.                au   diob := diob + 1;       (* count an additional high bit *)
  389.                ram  diob -> @PARITY_TEMP_UART;
  390.                end.
  391.  
  392. (* all data bits have been received and stored left justified in the shift- *)
  393. (* register if parity was enabled, parity is in BIT15 of the shift register *)
  394.  
  395. RECEIVE_STOP_UART:
  396.                if   psl = 1 then goto RXD_OK_UART, flush.
  397.                                                      (*stopbit must be high *)
  398.  
  399. SET_FE_FLAG_UART: au   a :=>> max.
  400.                                (* set Framing Error if stopbit was not high *)
  401.                                       (* stores $4000 into a, sets Bit 14 *)
  402.  
  403. (* now check the parity *)
  404. RXD_OK_UART:
  405.                if   @PARITY_OFF_UART then goto PAR_OK_UART,flush.
  406.                                                         (* Parity enabled ? *)
  407.  
  408.                au   diob :=<< diob;            (* remove Parity *)
  409.                ram  p <- @PARITY_TEMP_UART.
  410.  
  411.                if   @PARITY_EVEN_UART then goto EVEN_PAR_UART,flush.
  412.  
  413.                au   p := p + 1.       (* for odd parity, negate it *)
  414.  
  415. EVEN_PAR_UART: au   nil :=>> p,ccl.   (* copy LSB from PARITY_TEMP to Carry *)
  416.  
  417.                if   C = 0 then goto PAR_OK_UART,flush.
  418.  
  419. (* there was a parity error *)
  420.                au   a := a + max. (*set Parity error, $8000, Bit 15 chan set*)
  421.  
  422. (* now move the left justified value in the shiftregister to right *)
  423. (* to have a right justified result *)
  424.  
  425. PAR_OK_UART:        ram  p <- @DATA_SIZE_UART.
  426.  
  427. (* calculate number of bits to shift right *)
  428.  
  429.                au   dec := dec - p;          (* align to the right side *)
  430.                chan pac := high_low;         (* init for new startbit *)
  431.                     chan clear flag0;neg_tdl,neg_mrl.
  432.  
  433.                repeat;
  434.                  au   diob :=>> diob.        (* align data right *)
  435.  
  436.                au   diob := diob + a;      (* combine data and flags *)
  437.                ram  diob -> @DATA_UART.      (* and store received dataword *)
  438.  
  439.                chan cir;                     (* generate RDRF-interrupt *)
  440.                end.
  441.  
  442.  
  443.  
  444. (**********************************************************************)
  445. (*     UNDEFINED ENTRIES - execute an end.                            *)
  446. (**********************************************************************)
  447. %entry start_address END_OF_LINK;
  448. name = UART_UNDEF;
  449. cond hsr1 = 0,hsr0 = 1.
  450.  
  451. %entry start_address END_OF_LINK; disable_match;
  452. name = UART_UNDEF;
  453. cond hsr1 = 0, hsr0 = 0, m/tsr = 0, lsr = 1, pin = x, flag0 = x.
  454.  
  455. %entry start_address END_OF_LINK; disable_match;
  456. name = UART_UNDEF;
  457. cond hsr1 = 0, hsr0 = 0, m/tsr = 1, lsr = 1, pin = x, flag0 = x.
  458.